package model.action.order_deal_action;

import java.io.IOException;
import java.util.Date;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import model.action.basic_function_action.RegisterConsumerAction;
import model.dap.dao.ConsumerDAO;
import model.dap.dao.DealDAO;
import model.dap.dao.MailConfigDAO;
import model.dap.dao.OrderDealDAO;
import model.dap.domain.Consumer;
import model.dap.domain.Deal;
import model.dap.domain.Log;
import model.dap.domain.MailConfig;
import model.dap.domain.OrderDeal;
import model.dap.mapper.ConsumerMapper;
import model.dap.mapper.DealMapper;
import model.dap.mapper.MailConfigMapper;
import model.dap.mapper.OrderDealMapper;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.ModelDriven;
import common.base.BaseAction;
import common.util.ValidateUtil;

@Results({
		@Result(name = "orderForm", type = "tiles", location = "tiles.OrderDeal"),
		@Result(name = "success", type = "tiles", location = "tiles.OrderDeal"),
		@Result(name = "errorex", type = "tiles", location = "tiles.OrderDeal"),
		@Result(name = "successCx", type = "redirectAction", location = "orderform.html?nextPage=orderForm"),
		@Result(name = "ERROR", type = "tiles", location = "tiles.error") })
@ParentPackage("master_login")
public class OrderDealAction extends BaseAction implements
		ModelDriven<OrderDeal> {

	/**
	 * 
	 */
	protected static Logger log = Logger
			.getLogger(RegisterConsumerAction.class);
	private static final long serialVersionUID = 1L;
	private Deal deal = new Deal();
	private OrderDeal orderdeal = new OrderDeal();
	private int quantity;
	private double dealbuytotal, dealtotal;
	private int sellpr;
	private int dealID;
	private int totalamount;
	private Date now = new Date();
	private boolean emailCheck = false;

	public boolean isEmailCheck() {
		return emailCheck;
	}

	public void setEmailCheck(boolean emailCheck) {
		this.emailCheck = emailCheck;
	}

	private Consumer consumer = new Consumer();

	public Consumer getConsumer() {
		return consumer;
	}

	public void setConsumer(Consumer consumer) {
		this.consumer = consumer;
	}

	private static int errTimes = 0;
	private String to;
	private int typeID;

	public int amountTemp1;
	private String noteship;

	public int getAmountTemp1() {
		return amountTemp1;
	}

	public void setAmountTemp1(int amountTemp1) {
		this.amountTemp1 = amountTemp1;
	}

	public static int getErrTimes() {
		return errTimes;
	}

	public static void setErrTimes(int errTimes) {
		OrderDealAction.errTimes = errTimes;
	}

	public String getTo() {
		return to;
	}

	public void setTo(String to) {
		this.to = to;
	}

	public int getTypeID() {
		return typeID;
	}

	public void setTypeID(int typeID) {
		this.typeID = typeID;
	}

	// --- Bien cua mail------
	private static MailConfig mailConfig = new MailConfig();

	static Properties properties = new Properties();

	public static MailConfig getMailConfig() {
		return mailConfig;
	}

	public static void setMailConfig(MailConfig mailConfig) {
		OrderDealAction.mailConfig = mailConfig;
	}

	public static Properties getProperties() {
		return properties;
	}

	public static void setProperties(Properties properties) {
		OrderDealAction.properties = properties;
	}

	public int getDealID() {
		return dealID;
	}

	public void setDealID(int dealID) {
		this.dealID = dealID;
	}

	@Action("/master/orderform")
	public String orderForm() {
		loadParentDealCategory();
		getCityList2();
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpSession session = request.getSession();

		// ===================== GET SESSION DEAL ID
		String str = session.getAttribute("sessionDealID").toString();
		sessionDealID = Integer.parseInt(str);
		int dealID = sessionDealID;

		// int dealID = getSelectedDealID();
		DealMapper dealrmapper = new DealDAO();
		deal = dealrmapper.getDealbyID((dealID));
		// sellpr = ((int) deal.getSellPrice());
		amountTemp1 = deal.getTotalAmount();
		if (deal.getCurrencyID().equals("vnd")) {
			deal.setNewSellMoney(newMoney(deal.getSellPrice() + ""));
			// deal.setNewTotalMoney(newMoney(dealtotal+""));
		} else {
			deal.setNewSellMoney(deal.getSellPrice() + "");
		}
		// getDealbuytotal();
		// dealbuytotal=quantity*deal.getSellPrice();
		return "orderForm";

	}
	@Action("/master/order-deal")
	public String insertOrder() {
		getCityList2();
		loadParentDealCategory();
		int dealID = getSelectedDealID();
		DealMapper dealrmapper = new DealDAO();
		deal = dealrmapper.getDealbyID((dealID));
		int amountTemp2 = deal.getTotalAmount();
		if (deal.getCurrencyID().equals("vnd")) {
			deal.setNewSellMoney(newMoney(deal.getSellPrice() + ""));
		} else {
			deal.setNewSellMoney(deal.getSellPrice() + "");
		}
		if ((amountTemp1 == amountTemp2) || (amountTemp2 >= quantity)) {
			
			try {
				orderdeal.setUserID(getCurrentUser().getUserID());
				OrderDealMapper orderMapper = new OrderDealDAO();
				if (String.valueOf(quantity).toString() == null
						|| quantity == 0) {
					return "orderForm";
				}
				orderdeal.setNumberOrder(quantity);
				dealbuytotal = ((double) quantity) * deal.getSellPrice();
				orderdeal.setTotalCost(dealbuytotal);
				orderdeal.setNote(noteship);
				
				int results = orderMapper.insertOrder(orderdeal);
				if (results == 0) {
					showError("Có lỗi về tình trạng deal, Liên hệ với admin để biết thêm về tình trạng này");
					return "errorex";
				}

				insertLogO();
				updateDeal();
				// SEND EMAIL
				ConsumerMapper userMapper = new ConsumerDAO();
				setConsumer(userMapper.getConsumerbyId(orderdeal.getUserID()));
				execute(consumer.getEmail(), 2);
				if (emailCheck == true) {
					setSuccessmessage("Mua deal thành công! Thông tin đơn hàng của bạn đã được gửi vào "
							+ to);
				} else {
					setSuccessmessage("Mua deal thành công!");
				}
			} catch (Exception e) {
				return ERROR;
			}
		} else if ((deal.getEndDatetime().compareTo(now) <= 0)) {
			showError("Deal vừa hết hạn. Vui lòng chọn deal khác!");
			updateDealStatus3O();
		}
		if ((amountTemp1 != amountTemp2) && (amountTemp2 < quantity)) {
			showError("Mua deal không thành công");
		}
		return SUCCESS;
	}

	// update status deal
	public String updateDealStatus3O() {
		try {
			OrderDealMapper orderMapper = new OrderDealDAO();
			int result = orderMapper.updateDealStatus3O(orderdeal);
			if (result == 0) {
				showError("Có lỗi về tình trạng deal, Liên hệ với admin để biết thêm về tình trạng này");
				return "errorex";
			}
			return SUCCESS;
		} catch (Exception e) {
			// TODO: handle exception
			return ERROR;
		}
	}

	// set table Deal
	
	public String updateDeal() {
		try {
			String type = ServletActionContext.getRequest().getMethod();

			if (type.toUpperCase() == "GET") {
				return "successCx";
			}
			getCityList2();
			loadParentDealCategory();
			OrderDealMapper orderMapper = new OrderDealDAO();
			orderdeal.setNumberOrder(quantity);
			int result = orderMapper.updateDeal(orderdeal);
			if (result == 0) {
				showError("Có lỗi về tình trạng deal, Liên hệ với admin để biết thêm về tình trạng này");
				return "errorex";
			}
				
			return SUCCESS;
		} catch (Exception e) {
			// TODO: handle exception
			return ERROR;
		}
	}

	public Deal getDeal() {
		return deal;
	}

	public void setDeal(Deal deal) {
		this.deal = deal;
	}

	public int getQuantity() {
		return quantity;
	}

	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}

	public double getDealbuytotal() {
		return dealbuytotal;
	}

	public void setDealbuytotal(double dealbuytotal) {
		this.dealbuytotal = dealbuytotal;
	}

	public int getSellpr() {
		return sellpr;
	}

	public void setSellpr(int sellpr) {
		this.sellpr = sellpr;
	}

	public OrderDeal getOrderdeal() {
		return orderdeal;
	}

	public void setOrderdeal(OrderDeal orderdeal) {
		this.orderdeal = orderdeal;
	}

	@Override
	public OrderDeal getModel() {
		// TODO Auto-generated method stub
		return orderdeal;
	}

	public int getTotalamount() {
		return totalamount;
	}

	public void setTotalamount(int totalamount) {
		this.totalamount = totalamount;
	}

	public Log getInsertlog() {
		return insertlog;
	}

	public void setInsertlog(Log insertlog) {
		this.insertlog = insertlog;
	}

	public String getNoteship() {
		return noteship;
	}

	public void setNoteship(String noteship) {
		this.noteship = noteship;
	}

	// ---------------SEND MAIL----------------------------------------------
	public void execute(String sTo, int sTypeID) throws IOException {
		setTo(sTo);
		setTypeID(sTypeID);

		MailConfigMapper mailConfigMapper = new MailConfigDAO();
		mailConfig = mailConfigMapper.selectMailConfigByID(typeID);

		String socketPort = (" " + mailConfig.getSmtpSocketPort()).trim();
		String socketClass = (" " + mailConfig.getSmtpSocketClass()).trim();
		properties.put("mail.smtp.host", mailConfig.getSmtpHost());

		if (ValidateUtil.validateEmptyString(socketPort) == false
				&& ValidateUtil.validateEmptyString(socketClass) == false) {
			properties.put("mail.smtp.socketFactory.port",
					mailConfig.getSmtpSocketPort());
			properties.put("mail.smtp.socketFactory.class",
					mailConfig.getSmtpSocketClass());
		}
		properties.put("mail.smtp.auth", mailConfig.getSmtpAuth());
		properties.put("mail.smtp.port", mailConfig.getSmtpPort());
		properties.put("mail.smtp.password", mailConfig.getPassword());

		try {
			if (ValidateUtil.validateEmptyString(socketPort) == false
					&& ValidateUtil.validateEmptyString(socketClass) == false) {
				Session session = Session.getDefaultInstance(properties,
						new javax.mail.Authenticator() {
							protected PasswordAuthentication getPasswordAuthentication() {
								return new PasswordAuthentication(mailConfig
										.getFrom(), mailConfig.getPassword());
							}
						});

				// encording utf8 - subject
				byte[] pSubject = mailConfig.getSubject().getBytes("UTF-8");
				String subjectValue = new String(pSubject, "UTF-8");
				// encording utf8 - body
				/*
				 * String iBody=mailConfig.getBody()+
				 * " Sau đây là thông tin đơn đặt hàng của bạn: "
				 * +deal.getDealName
				 * ()+" - Số lượng là: "+orderdeal.getNumberOrder
				 * ()+" - Tổng cộng đơn hàng:"+orderdeal.getTotalCost(); byte[]
				 * pBody = iBody.getBytes("UTF-8"); String bodyValue = new
				 * String(pBody, "UTF-8");
				 */

				Message message = new MimeMessage(session);
				message.setFrom(new InternetAddress(mailConfig.getFrom()));
				message.setRecipients(Message.RecipientType.TO,
						InternetAddress.parse(to));
				message.setSubject(subjectValue);
				// message.setText(bodyValue);
				message.setContent(
						mailConfig.getBody()
								+ "<br>&nbsp;</br>"
								+ "<table style='background-color:white;'>"
								+ "<tr style='background-color:#00A8F6;color:white;'>"
								+ "<td>" + "<p>&nbsp;Deal&nbsp;&nbsp;</p>"
								+ "</td>" + "<td>"
								+ "<p>&nbsp;Số lượng&nbsp;</p>" + "</td>"
								+ "<td>" + "<p>&nbsp;Đơn giá(VNĐ)&nbsp;</p>"
								+ "</td>" + "<td>"
								+ "<p>&nbsp;Thanh toán(VNĐ)&nbsp;</p>"
								+ "</td>" + "</tr>" + "<tr>" + "<td>&nbsp;"
								+ deal.getDealName() + "</td>" +

								"<td>&nbsp;" + orderdeal.getNumberOrder()
								+ "</td>" +

								"<td>&nbsp;" + deal.getSellPrice() + "</td>"
								+ "<td>&nbsp;" + orderdeal.getTotalCost()
								+ "</td>" + "</tr>", "text/html; charset=utf-8");
				Transport.send(message);
				emailCheck = true;
			} else {
				// Get the default Session object.
				Session session = Session.getDefaultInstance(properties, null);

				// Create a default MimeMessage object.
				MimeMessage message = new MimeMessage(session);

				// Set From: header field of the header.
				message.setFrom(new InternetAddress(mailConfig.getFrom()));

				// Set To: header field of the header.
				message.addRecipient(Message.RecipientType.TO,
						new InternetAddress(to));

				// Set Subject: header field
				message.setSubject(mailConfig.getSubject(), "UTF-8");

				// get username in from
				String[] fromItems = mailConfig.getFrom().split("@");
				String username = fromItems[0];

				// Now set the actual message
				// message.setText(mailConfig.getBody()+" Sau đây là thông tin đơn đặt hàng của bạn: "+deal.getDealName()+" - Số lượng là: "+orderdeal.getNumberOrder()+" - Tổng cộng đơn hàng:"+orderdeal.getTotalCost(),
				// "UTF-8");

				message.setContent(
						mailConfig.getBody()
								+ "<br>&nbsp;</br>"
								+ "<table style='background-color:white;'>"
								+ "<tr style='background-color:#00A8F6;color:white;'>"
								+ "<td>" + "<p>&nbsp;Deal&nbsp;&nbsp;</p>"
								+ "</td>" + "<td>"
								+ "<p>&nbsp;Số lượng&nbsp;</p>" + "</td>"
								+ "<td>" + "<p>&nbsp;Đơn giá(VNĐ)&nbsp;</p>"
								+ "</td>" + "<td>"
								+ "<p>&nbsp;Thanh toán(VNĐ)&nbsp;</p>"
								+ "</td>" + "</tr>" + "<tr>" + "<td>&nbsp;"
								+ deal.getDealName() + "</td>" +

								"<td>&nbsp;" + orderdeal.getNumberOrder()
								+ "</td>" +

								"<td>&nbsp;" + deal.getSellPrice() + "</td>"
								+ "<td>&nbsp;" + orderdeal.getTotalCost()
								+ "</td>" + "</tr>", "text/html; charset=utf-8");
				Transport transport = session.getTransport("smtp");
				transport.connect(mailConfig.getSmtpHost(), username,
						mailConfig.getPassword());
				transport.sendMessage(message, message.getAllRecipients());
				transport.close();
				emailCheck = true;
			}

		} catch (Exception e) {
			setErrTimes(errTimes + 1);
			if (errTimes > 1) {
				log.error("Send mail order deal fail for "
						+ consumer.getUserID() + " with email address: " + to
						+ " times 2.");
				setErrTimes(0);
			} else {
				log.error("Send mail order deal fail for "
						+ consumer.getUserID() + " with email address: " + to
						+ " times 1.");
				execute(consumer.getEmail(), 2);
				emailCheck = false;
			}
			emailCheck = false;
		}
	}

	public double getDealtotal() {
		return dealtotal;
	}

	public void setDealtotal(double dealtotal) {
		this.dealtotal = dealtotal;
	}
}
